package pe.gob.proviasnac.app.model;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import pe.gob.proviasnac.app.utiles.Criteria;
import com.opensymphony.xwork2.ActionSupport;

public class ModelHelper extends ActionSupport {
	
	private static final long serialVersionUID = 1996034945419608360L;
	protected SqlSession session;
	
	   public SqlSession getSession() {
		return session;
	}

	public void setSession(SqlSession session) {
		this.session = session;
	}

	public void actualizar(Object object) throws Exception {
	        try {
	            this.updateByPrimaryKey(object);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	    }
	   
	public void insertar(Object object) throws Exception {
	        try {
	            this.insert(object);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	    }
		
    public void eliminar(Class mapperClass, Object obj) throws Exception {
        invokeCRUDOperation(mapperClass, obj, "deleteByPrimaryKey");
    }
    
	    public void commit() throws SQLException {
	        
	        if (session != null){
	            System.out.println("commit");
	            session.getConnection().commit();
	        }
	    }

	    public void close() throws SQLException {
	        if (session != null){
	            System.out.println("close");
	            session.close();
	        }
	    }
	    
	    public void rollback() throws SQLException {
	        if (session != null){
	            System.out.println("rollback");
	            session.rollback();
	        }
	    }

	   private void insert(Class mapperClass, Object obj) throws Exception {
	        invokeCRUDOperation(mapperClass, obj, "insert");
	    }

	    private void insert(Object obj) throws Exception {
	        try {
	            insert(findMapperClass(obj), obj);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	    }

	    private void updateByPrimaryKey(Object obj) throws Exception {
	        try {
	            updateByPrimaryKey(findMapperClass(obj), obj);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	    }
	    
	    private void updateByPrimaryKey(Class mapperClass, Object obj) throws Exception {
	        invokeCRUDOperation(mapperClass, obj, "updateByPrimaryKey");
	    }
	    
	    public Object selectByPrimaryKey(Class mapperClass, Integer id) throws Exception {
	        try {
	            String operation = mapperClass.getName() + ".selectByPrimaryKey";
	            List list = session.selectList(operation, id);
	            if (list == null) {
	            	return null;
	            }else{
	            	return list.get(0);
	            }
	            
	        } catch (Exception e) {
	        	e.printStackTrace();
	        	return null;
	        }
	       
	    }
	    
	    private Class findMapperClass(Object obj) throws ClassNotFoundException {
	        Class c;
	        String className = obj.getClass().getName();
	        className = className.replaceFirst("dto", "dao") + "Mapper";
	        System.out.println(className);
	        c =  Class.forName(className);       
	        return c;
	    }

	    private void invokeCRUDOperation(Class mapperClass, Object obj, String operation) throws Exception {
	        if (session != null) {
	            for (Method method : mapperClass.getMethods()) {
	                if (method.getName().equals(operation)) {
	                    Object mapper = session.getMapper(mapperClass);
	                    Object parameters[] = { obj };
	                    try {

	                        method.invoke(mapper, parameters);
	                        System.out.println(operation);
	                    } catch (IllegalAccessException e) {
	                          e.printStackTrace();
	                    } catch (InvocationTargetException e) {
	                          e.printStackTrace();
	                    }
	                    break;
	                }
	            }
	        }
	    }
		public List selectByCriteria(String nomQuery, Criteria criteria) {
			try {
				String operation = "pe.gob.proviasnac.app.dao."+nomQuery+"Mapper"+"." + this.getNombreMetodoLower(nomQuery);
				System.out.println("Operacion: " + operation);
				List result = session.selectList(operation, criteria);
				if (result == null) {
					result = new ArrayList();
				}
				return result;
			} catch (Exception e) {
				e.printStackTrace();
				e.getMessage();
				return null;
			}
		}
		
		private String getNombreMetodoLower(String nombreMetodo){
			return nombreMetodo.substring(0, 1).toLowerCase() + nombreMetodo.substring(1, nombreMetodo.length());
		}
}
